from rest_framework import serializers

from api.serializers.address_serializer import MailingAddressSerializer
from app.models import MailingAddress, ProductSpec
from app.models.order import OrderProduct, Order
from app.models.pay_method import PayMethod
from app.models.pre_order import PreOrder
from app.utils import format_datetime


class OrderProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderProduct
        fields = '__all__'


class OrderAddProductSerializer(serializers.Serializer):
    spec = serializers.PrimaryKeyRelatedField(queryset=ProductSpec.objects.all())
    amount = serializers.IntegerField(min_value=0)


class OrderAddSerializer(serializers.Serializer):
    pre_order_id = serializers.PrimaryKeyRelatedField(queryset=PreOrder.objects.all())
    address = serializers.PrimaryKeyRelatedField(queryset=MailingAddress.objects.all())
    remark = serializers.CharField(default='', allow_blank=True, allow_null=True, required=False)
    delivery_datetime = serializers.DateTimeField(input_formats=["%Y%m%d%H%M"])
    delivery_deadline_datetime = serializers.DateTimeField(input_formats=["%Y%m%d%H%M"])


class OrderUpdateSerializer(serializers.Serializer):
    remark = serializers.CharField(required=False)
    delivery_datetime = serializers.DateTimeField(input_formats=["%Y%m%d%H%M"], required=False)
    pay_method = serializers.PrimaryKeyRelatedField(queryset=PayMethod.objects.all(), required=False)


class OrderUpdateStatusSerializer(serializers.Serializer):
    order_id = serializers.PrimaryKeyRelatedField(queryset=Order.objects.all())


class OrderProductResponseSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderProduct
        fields = '__all__'

    def to_representation(self, product: OrderProduct):
        return dict(spec_id=product.spec.id,
                    spec_name=product.spec.name,
                    product_name=product.product_name,
                    price=product.price,
                    uint=product.unit,
                    amount=product.amount,
                    image=product.image_url,
                    deposit=product.deposit,
                    discount=product.discount,
                    deposit_desc=product.deposit_desc)


class OrderResponseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'

    def to_representation(self, order: Order):
        data = dict(order_id=order.id,
                    created_datetime=format_datetime(order.created_datetime),
                    expired_datetime=format_datetime(order.expired_datetime),
                    status_code=order.status,
                    status_display=order.get_status_display(),
                    sum=order.sum,
                    remark=order.remark,
                    address=MailingAddressSerializer(order.address).data,
                    delivery_datetime=order.delivery_datetime,
                    delivery_deadline_datetime=order.delivery_deadline_datetime,
                    products=OrderProductResponseSerializer(order.products, many=True).data,
                    out_order_id=order.out_order_id,
                    pay_description=u'华焱农贸消费',
                    all_deposit=self.sum_deposit(order.products.all()),
                    merchant_name=order.user.merchant_name)
        if order.pay_method:
            data.update(dict(pay_method_name=order.pay_method.name, pay_method_id=order.pay_method.id))
        return data

    @staticmethod
    def sum_deposit(products):
        all_deposit = 0
        if products:
            for product in products:
                all_deposit += product.deposit * product.amount
        return all_deposit


class OrderListRequestSerializer(serializers.Serializer):
    page = serializers.IntegerField()


class OrderListResponseSerializer(serializers.Serializer):
    has_more = serializers.BooleanField()
    orders = OrderResponseSerializer(many=True)
